package cn.disicn.model;

import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

import cn.disicn.common.Const;
import cn.disicn.common.ServerResponse;
import cn.disicn.model.base.BaseSecPublishPayLog;
import cn.disicn.util.DateTimeUtil;
import cn.disicn.util.PageSource;
import cn.disicn.vo.TransactionRecordVo;

/**
 * Generated by JFinal.
 */
@SuppressWarnings("serial")
public class SecPublishPayLog extends BaseSecPublishPayLog<SecPublishPayLog> {

	public static final SecPublishPayLog dao = new SecPublishPayLog().dao();

	/**
	 * 分页查询所有用户的交易记录
	 * 
	 * @param type
	 * @param orderNo
	 * @param pageNum
	 * @param pageSize
	 * @param userId
	 * @return
	 */
	public ServerResponse<PageSource<TransactionRecordVo>> getAllTransactionRecord(Integer type, String orderNo,
			Integer pageNum, Integer pageSize) {
		// 判断订单号格式是否正确
		if (!StringUtils.isBlank(orderNo)) {
			String regOrderNo = "\\d{13}";
			if (!orderNo.matches(regOrderNo)) {
				return ServerResponse.createByErrorMsg(Const.ErrorResult.PARAMETER_ERROR);
			}
		}
		StringBuilder sql = new StringBuilder();
		// 判断是否指定查询的交易类型
		if (type != null && !type.equals("")) {
			if (type == Const.TransactionType.RECHARGE) {
				sql.append(
						"SELECT id,publishUserId,orderNo,amount,`status`,paymentTime,createTime,chargeInfo FROM sec_publish_charge_log");
			} else if (type == Const.TransactionType.CONSUMPTION) {
				sql.append(
						"SELECT id,publishUserId,orderNo,amount,`status`,paymentTime,createTime,jobId FROM sec_publish_pay_log");
			} else if (type == Const.TransactionType.REFUND) {
				sql.append(
						"SELECT id,publishUserId,orderNo,amount,`status`,refundTime,createTime FROM sec_publish_refund_info");
			} else {
				return ServerResponse.createByErrorMsg(Const.ErrorResult.PARAMETER_ERROR);
			}
			if (!StringUtils.isBlank(orderNo)) {
				sql.append(" where orderNo = '" + orderNo + "'");
			}
		} else {
			sql.append(
					"SELECT id,publishUserId,orderNo,amount,`status`,paymentTime,createTime,chargeInfo FROM sec_publish_charge_log");
			if (!StringUtils.isBlank(orderNo)) {
				sql.append(" where orderNo = '" + orderNo + "'");
			}
			sql.append(
					" UNION SELECT id,publishUserId,orderNo,amount,`status`,paymentTime,createTime,jobId FROM sec_publish_pay_log");
			if (!StringUtils.isBlank(orderNo)) {
				sql.append(" where orderNo = '" + orderNo + "'");
			}
			sql.append(
					" UNION SELECT id,publishUserId,orderNo,amount,`status`,refundTime,createTime,jobId FROM sec_publish_refund_info");
			if (!StringUtils.isBlank(orderNo)) {
				sql.append(" where orderNo = '" + orderNo + "'");
			}
			sql.append(" ORDER BY createTime DESC");
		}
		// 查询该条件下记录的总数
		List<Object> query = Db.query(sql.toString());

		Integer count = 0;
		if (query != null) {
			count = query.size();
		} else {
			return ServerResponse.createByError();
		}
		// 执行分页
		sql.append(" limit ?,?");
		// 执行查询
		List<Record> find = Db.find(sql.toString(), pageNum, pageSize);

		// 返回数据
		return ServerResponse.createBySuccess(
				new PageSource<TransactionRecordVo>(pageNum, pageSize, null, count, assembleTransactionRecordVo(find)));
	}

	/**
	 * 封装交易记录vo
	 * 
	 * @param payLogList
	 * @param userId
	 * @return
	 */
	private List<TransactionRecordVo> assembleTransactionRecordVo(List<Record> list) {
		List<TransactionRecordVo> recordVoList = Lists.newArrayList();
		for (Record record : list) {
			TransactionRecordVo recordVo = new TransactionRecordVo();
			String paymentOrRefundTime = "";
			if (record.getDate("paymentTime") != null) {
				paymentOrRefundTime = DateTimeUtil.dateToStr(record.getDate("paymentTime"), "yyyy-MM-dd HH:mm:ss");
			} else if (record.getDate("refundTime") != null) {
				paymentOrRefundTime = DateTimeUtil.dateToStr(record.getDate("refundTime"), "yyyy-MM-dd HH:mm:ss");
			} else {
				paymentOrRefundTime = "- - -";
			}
			recordVo.setPaymentOrRefundTime(paymentOrRefundTime);
			recordVo.setCreateTime(DateTimeUtil.dateToStr(record.getDate("createTime"), "yyyy-MM-dd HH:mm:ss"));
			recordVo.setOrderAmount(record.getBigDecimal("amount").toString());
			recordVo.setOrderNo(record.getLong("orderNo").toString());
			String paymentMethod = "";
			String paymentOrRefundState = "";
			String typeOfTransaction = "";
			if (Integer.parseInt(record.get("status").toString()) < 10) {
				typeOfTransaction = "推广任务撤回退款";
				paymentMethod = getPlatfromByOrderNo(record.getLong("orderNo").toString());
				paymentOrRefundState = Const.RefundStatusEnum.codeOf(Integer.parseInt(record.get("status").toString()))
						.getValue();
			} else {
				if (record.get("chargeInfo") != null && record.get("chargeInfo").toString().length() == 32
						|| record.get("jobId") != null && record.get("jobId").toString().length() == 32) {
					typeOfTransaction = Const.PaymentProduct.RELEASETASK;
				} else {
					typeOfTransaction = Const.PaymentProduct.RECHARGE;
				}
				if (Integer.parseInt(record.get("status").toString()) >= Const.OrderStatusEnum.PAID.getCode()) {
					paymentMethod = getPlatfromByOrderNo(record.getLong("orderNo").toString());
				} else {
					paymentMethod = "- - -";
				}
				paymentOrRefundState = Const.OrderStatusEnum.codeOf(Integer.parseInt(record.get("status").toString()))
						.getValue();
			}
			recordVo.setPaymentMethod(paymentMethod);
			recordVo.setPaymentOrRefundState(paymentOrRefundState);
			recordVo.setTypeOfTransaction(typeOfTransaction);

			recordVoList.add(recordVo);
		}
		return recordVoList;
	}

	/**
	 * 通过用户Id和订单号查询付款平台
	 * 
	 * @param orderNo
	 * @param userId
	 * @return
	 */
	private String getPlatfromByOrderNo(String orderNo) {
		SecPublishPayInfo pay = SecPublishPayInfo.dao
				.findFirst("select payPlatform from sec_publish_pay_info where orderNo = ?", orderNo);
		if (pay != null) {
			return Const.PayTypeEnum.codeOf(pay.getPayPlatform()).getValue();
		}
		return "- - -";
	}

	/**
	 * 查询全部的订单号
	 * 
	 * @param userId
	 * @return
	 */
	public Set<String> getAllOrderNo() {
		List<SecPublishPayLog> payLogList = dao
				.find("SELECT orderNo FROM sec_publish_pay_log UNION SELECT orderNo FROM "
						+ "sec_publish_charge_log GROUP BY orderNo");
		Set<String> orderNoSet = Sets.newHashSet();
		for (SecPublishPayLog payLog : payLogList) {
			if (payLog.getOrderNo() != null) {
				orderNoSet.add(payLog.getOrderNo().toString());
			}
		}
		return orderNoSet;
	}

}
